package com.example.tech34Base64.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

/**
 * Created by Ben.Wang
 * <p>
 * author     : Ben.Wang
 * date       : 2021/6/25 17:09
 * description:
 * 唯一需要注意的是，如果你要转换的base64是不带DataURI的，那你有两个选择，
 *
 * 第一种方法就是自己按照实际情况创建一个，如示例代码那样。
 * 第二种方法就是采用另外一个构造函数
 * ————————————————
 * 主题名称：Base64如何转MultipartFile（对流行实现类BASE64DecodedMultipartFile的修正）
 * 版权声明：本文为CSDN博主「ShuSheng007」的原创文章，遵循CC 4.0 BY-SA版权协议，转载请附上原文出处链接及本声明。
 * 原文链接：https://blog.csdn.net/ShuSheng0007/article/details/118230374
 */
public class Base64ToMultipartFile implements MultipartFile {

    private static final Logger LOGGER = LoggerFactory.getLogger(Base64ToMultipartFile.class);

    private final byte[] fileContent;

    private final String extension;
    private final String contentType;


    /**
     * @param base64
     * @param dataUri     格式类似于: data:image/png;base64
     *
     //1.使用java8的java.util.Base64报“java.lang.IllegalArgumentException: Illegal base64 character d”的问题
     //2.原因：因为生产环境中实际运行并不跟我的case一致，生产我们是接入合作机构的base64数据进行解码，但是对方用的不是java8的Base64编码，于是发生了异常!
     //3.解决方法： Base64.getDecoder().decode() 修改为 Base64.getMimeDecoder().decode()
     //————————————————
     //版权声明：本文为CSDN博主「墨9」的原创文章，遵循CC 4.0 BY-SA版权协议，转载请附上原文出处链接及本声明。
     //原文链接：https://blog.csdn.net/m0_37732829/article/details/95504682
     */
    public Base64ToMultipartFile(String base64, String dataUri) {
        byte[] fileContentTEMP;
        try {
            //2.其他加密方式解密：getMimeDecoder，视具体情况进行解密
            fileContentTEMP = Base64.getMimeDecoder().decode(base64.getBytes(StandardCharsets.UTF_8));
        }catch (Exception e) {
            //1.标准jdk8的解码方法：getDecoder
            fileContentTEMP = Base64.getDecoder().decode(base64.getBytes(StandardCharsets.UTF_8));
            LOGGER.info("非标准jdk解密失败，使用标准方式解密");
        }
        this.fileContent = fileContentTEMP;
        this.extension = dataUri.split(";")[0].split("/")[1];
        this.contentType = dataUri.split(";")[0].split(":")[1];
    }

    public Base64ToMultipartFile(String base64, String extension, String contentType) {
        this.fileContent = Base64.getDecoder().decode(base64.getBytes(StandardCharsets.UTF_8));
        this.extension = extension;
        this.contentType = contentType;
    }

    @Override
    public String getName() {
        return "param_" + System.currentTimeMillis();
    }

    @Override
    public String getOriginalFilename() {
        return "file_" + System.currentTimeMillis() + "." + extension;
    }

    @Override
    public String getContentType() {
        return contentType;
    }

    @Override
    public boolean isEmpty() {
        return fileContent == null || fileContent.length == 0;
    }

    @Override
    public long getSize() {
        return fileContent.length;
    }

    @Override
    public byte[] getBytes() throws IOException {
        return fileContent;
    }

    @Override
    public InputStream getInputStream() throws IOException {
        return new ByteArrayInputStream(fileContent);
    }

    @Override
    public void transferTo(File file) throws IOException, IllegalStateException {
        try (FileOutputStream fos = new FileOutputStream(file)) {
            fos.write(fileContent);
        }
    }

    //base64解码使用
    public static void main(String[] args) {
        //base64编码后的图片有头信息所以要分离出来：data[1]：图片内容为索引  data[0]:image/png;base64,
        String base64 = "......";//传入数据格式
        final String[] base64Array = base64.split(",");
        String dataUir, data;
        if (base64Array.length > 1) {
            dataUir = base64Array[0];
            data = base64Array[1];
        } else {
            //根据你base64代表的具体文件构建
            dataUir = "data:image/jpg;base64";
            data = base64Array[0];
        }
        MultipartFile multipartFile = new Base64ToMultipartFile(data, dataUir);
    }
}
